#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

// 定义接收信号的函数指针
static void int_handler(int s)
{
	write(1, "!", 1);
}
/*
 * 信号集，对一组信号的阻塞和放开，与信号的恢复
 * sigprocmask(参数1，参数2，参数3)
 * 参数1：	SIG_BLOCK		阻塞信号
 * 			SIG_UNBLOCK		放开信号
 * 			SIG_SETMASK		恢复信号
 * 参数2：信号集
 * 参数3：信号集
 * */
int main()
{

	int i;

	// 注册一个处理SIGINT信号的方式，SIG_IGN表示忽略该信号, 当按住Ctrl + c 的时候终止信号被忽略
	//signal(SIGINT,SIG_IGN);
	// 当收到SIGINT信号，会触发int_handler指针函数
	signal(SIGINT,int_handler);
	sigset_t set, oset, sset;
	
	sigemptyset(&set); 			// 清空信号集
	sigaddset(&set, SIGINT);	// 添加信号
	// 在编写程序的时候需要，需要考虑自己所处于一个模块之中，要考虑当前信号集的状态，在进入和出去，需要保证信号集的状态不变，需要使用sset保存信号集的状态
	// 一般先让信号集处于UNBLOCK状态，并且保存之前的状态到sset
	sigprocmask(SIG_UNBLOCK, &set, &sset);
	
	for (i = 0; i < 200; i++) {
		// 进入前，先阻塞信号集
		sigprocmask(SIG_BLOCK, &set, &oset);
		for (i = 0; i < 10; i++) {
			write(1, "*", 1);
			sleep(1);
		}		
		sigprocmask(SIG_UNBLOCK, &oset, NULL);
		write(1, "\n", 1);
	}

	// 功能执行完毕需要使用SIG_SETMASK恢复到之前的信号集状态
	sigprocmask(SIG_SETMASK, &sset, NULL);

	exit(0);
}
